package com.yanyuhang.service.impl;

import com.yanyuhang.entity.Organization;
import com.yanyuhang.service.PersonRepo;
import org.springframework.ldap.core.*;
import org.springframework.ldap.core.support.BaseLdapNameAware;
import org.springframework.ldap.support.LdapNameBuilder;

import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.ldap.LdapName;
import java.util.List;

import static org.springframework.ldap.query.LdapQueryBuilder.query;

/**
 * @author yyh
 * @create 2021-02-20 13:49
 */
public class PersonRepoImpl implements PersonRepo,BaseLdapNameAware {

    private LdapTemplate ldapTemplate;

    public void setLdapTemplate(LdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
    }

    private LdapName basePath;

    @Override
    public void setBaseLdapPath(LdapName basePath) {
        this.basePath = basePath;
    }

    @Override
    public LdapName getFullPersonDn(Organization person) {
        return LdapNameBuilder.newInstance(basePath)
                .add(person.getName())
                .build();
    }


    //AttributesMapper返回单个属性
    @Override
    public List<String> getAllPersonNames() {
        return ldapTemplate.search(
                query().where("objectclass").is("organizationalUnit"),
                new AttributesMapper<String>() {
                    @Override
                    public String mapFromAttributes(Attributes attrs)
                            throws NamingException {
                        return attrs.get("ou").get().toString();
                    }
                });
    }

    private class PersonAttributesMapper implements AttributesMapper<Organization> {

        @Override
        public Organization mapFromAttributes(Attributes attrs) throws NamingException {
            Organization person = new Organization();
            person.setName((String)attrs.get("ou").get());
            return person;
        }
    }

    @Override
    public List<Organization> getAllPersons() {
        return ldapTemplate.search(query()
                .where("objectclass").is("organizationalUnit"), new PersonAttributesMapper());
    }

    @Override
    public List<Organization> getOneLevelPersons() {
//        return ldapTemplate.search(query()
//                .where("objectclass").is("organizationalUnit"), new PersonAttributesMapper());
         return ldapTemplate.search(
                query().base("dc=三亚市,dc=com")
                        .where("objectclass").is("person"),
                new PersonAttributesMapper());
    }




    @Override
    public Organization findPerson(String dn) {
        return ldapTemplate.lookup(dn, new PersonAttributesMapper());
    }

//    public static final String BASE_DN = "ou=三亚市,dc=hainan,dc=com";

    //我在配置文件中已有basedn,所以这里就不需要了

    @Override
    public Name buildDn(Organization p) {
        return LdapNameBuilder.newInstance()
                .add("ou", p.getName())
                .build();
    }

    @Override
    public Name buildDn(String ou){
        return LdapNameBuilder.newInstance()
                .add("ou", ou)
                .build();
    }

    //新增数据
    @Override
    public void create(Organization p) {
        Name dn = buildDn(p);
        System.out.println(dn);
        ldapTemplate.bind(dn, null, buildAttributes(p));
    }

    private Attributes buildAttributes(Organization p) {
        System.out.println(p);
        Attributes attrs = new BasicAttributes();
        BasicAttribute ocattr = new BasicAttribute("objectclass");
        ocattr.add("top");
        ocattr.add("organizationalUnit");
        attrs.put(ocattr);
        attrs.put("description", "Some Person");
        return attrs;
    }


    //通过使用添加数据DirContextAdapter
    @Override
    public void create2(Organization p) {
        Name dn = buildDn(p);
        DirContextAdapter context = new DirContextAdapter(dn);

        context.setAttributeValues("objectclass", new String[] {"organizationalUnit"});
        context.setAttributeValue("ou", p.getName());
//        context.setAttributeValue("sn", p.getLastname());
//        context.setAttributeValue("description", p.getDescription());

        ldapTemplate.bind(context);
    }

    @Override
    public void update(Organization p) {
        Name dn = buildDn(p);
        DirContextOperations context = ldapTemplate.lookupContext(dn);
        System.out.println(context);

        context.setAttributeValue("ou", "三十道德");
//        context.setAttributeValue("sn", p.getLastname());
//        context.setAttributeValue("description", p.getDescription());

        ldapTemplate.modifyAttributes(context);
    }

    //删除数据
    @Override
    public void delete(Organization p) {
        Name dn = buildDn(p);
        ldapTemplate.unbind(dn);
    }

    private static class PersonContextMapper implements ContextMapper {
        @Override
        public Object mapFromContext(Object ctx) {
            DirContextAdapter context = (DirContextAdapter)ctx;
            Organization p = new Organization();
            p.setName(context.getStringAttribute("ou"));
            return p;
        }
    }

    //使用一个ContextMapper搜索
    @Override
    public Organization findByPrimaryKey(String name) {
        Name dn = buildDn(name);
        PersonContextMapper personContextMapper = new PersonContextMapper();
        return (Organization) ldapTemplate.lookup(dn,personContextMapper );
    }
}
